"""
Copyright © 2025 Walkline Wang (https://walkline.wang)
Gitee: https://gitee.com/walkline/bemfa-cloud-sdk-for-micropython
"""
import esp
esp.osdebug(None)

import time
import asyncio
import network
import requests
from machine import Pin
from protocol.nonblocking_tcpclient import *

from dispatcher import Dispatcher
from button import Button


#region Config
LED_PIN = 48
BOOT_PIN = 0

BEMFA_SECRET_KEY = ''
BEMFA_TCP_SERVER = 'bemfa.com'
BEMFA_TCP_PORT = 8344

TOPIC = 'light002'

WIFI_SSID = ''
WIFI_PASSWORD = ''
#endregion


def printf(title, msg, *args, **kwargs):
	now = time.localtime()
	datetime = f'[{now[0]}-{now[1]:02d}-{now[2]:02d} {now[3]:02d}:{now[4]:02d}:{now[5]:02d}]'
	print(f'\033[0;34m{datetime}\033[1;37m{title}\033[0m {msg}', *args, **kwargs)


#region User Callbacks
def tcpclient_result_cb(result: dict):
	if result['cmd'] == COMMAND_SUBSCRIBE:
		printf('[sub]', 'Subscribe Successed' if result['res'] == 1 else 'Subscribe Failed')

	elif result['cmd'] == COMMAND_PUBLISH:
		printf('[pub]', 'Publish Successed' if result['res'] == 1 else 'Publish Failed')

	elif result['cmd'] == COMMAND_SUBSCRIBE_AND_PULL:
		printf('[last_msg]', f'topic: {result['topic']}, msg: {result['msg']}')

	elif result['cmd'] == COMMAND_GET_LAST_MESSAGE:
		printf('[new_msg]', f'time: {result['time']}, topic: {result['topic']}, msg: {result['msg']}')
		led(0 if result['msg'] == 'on' else 1)

	elif result['cmd'] == COMMAND_INTERNET_FAULT:
		printf('[wifi]', 'Internet Connection Lost')

	elif result['cmd'] == COMMAND_GET_DATETIME:
		printf('[datetime]', result)

	elif result['cmd'] == COMMAND_PING:
		pass

def buttons_click_cb(_):
	led(not led())
	client.publish(TOPIC, 'off' if led() else 'on', METHOD_UP)
#endregion


#region Tasks
async def check_network_connection():
	while True:
		if not sta.isconnected() or not client.wifi_connected:
			sta.active(False)
			sta.active(True)
			sta.connect(WIFI_SSID, WIFI_PASSWORD)

			while not sta.isconnected():
				await asyncio.sleep_ms(500)

			printf('[wifi]', 'WiFi Connected')

			try:
				response = requests.get('https://raw.giteeusercontent.com/walkline/WeatherStation/raw/master/success.html', timeout=3)

				if response.text == 'Success':
					printf('[wifi]', 'Internet Connected')

					client.wifi_connected = True
					client.connect()
					client.get_datetime()
					client.subscribe(TOPIC)
				else:
					printf('[wifi]', 'No Internet Connection, Code:', response.status_code)
			except OSError:
				printf('[wifi]', 'No Internet Connection')

		await asyncio.sleep_ms(5000)
		# printf('[wifi]', 'Check Network Connection')

async def setup():
	tasks = Dispatcher()
	button = Button(
		BOOT_PIN,
		click_cb=buttons_click_cb,
		timer_id=None
	)

	# 生成并添加定时器任务
	task_ping = lambda: client.ping()
	task_check_message = lambda: client.check_message()
	task_timer_callback = lambda: button.timer_callback()

	tasks.add_work(task_ping, 60_000)         # 发送心跳包
	tasks.add_work(task_check_message, 1_000) # 检查最新消息
	tasks.add_work(task_timer_callback, 20)   # 按键驱动检测
#endregion


async def main():
	printf('[main]', 'Start running')
	await asyncio.gather(check_network_connection(), setup())


if __name__ == '__main__':
	sta = network.WLAN(network.STA_IF)
	led = Pin(LED_PIN, Pin.OUT, value=1)

	client = TCPClient(
		BEMFA_TCP_SERVER,
		BEMFA_TCP_PORT,
		BEMFA_SECRET_KEY,
		tcpclient_result_cb)
	client.debug = False

	asyncio.run(main())
